package com.lagou.edu.users.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.jwt.crypto.sign.MacSigner;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

@Configuration
@EnableResourceServer // 开启资源服务器功能
@EnableWebSecurity //开启web访问安全
public class ResourceServerConfiger extends ResourceServerConfigurerAdapter {
    private String sign_key = "lagou_123";

    @Autowired
    private LagouAccessTokenConvertor lagouAccessTokenConvertor;

    /**
     * 该方法用于定义资源服务器向远程服务器发起请求进行token校验等事宜
     * @param resources
     * @throws Exception
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId("lagou_users_gateway")
                .tokenStore(tokenStore())
                .stateless(true);// 无状态设置
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http  //设置session的创建策略（根据需要创建即可）
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                .and()
                .authorizeRequests()
                .antMatchers("/user/info/**").authenticated() //info开头的请求需要认证
                .antMatchers("/user/test").authenticated() //test需要验证
                .anyRequest().permitAll(); // 其它请求不认证
    }

    /**
     * 该方法用于创建tokenStore对象（令牌存储对象）
     * token以什么方式存储
     */
    public TokenStore tokenStore(){
        // 这里token的存储方式也有多种，比如数据库、Redis、jwt
        // 这里我们返回内存存储，最终目标是用jwt存储到客户端。
//        return new InMemoryTokenStore();
        // 使用JWT令牌
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    /**
     * 返回JWT令牌转换器（帮助我们生产JWT令牌的）
     * 这里，我们可以把签名秘钥传递进去给转换器对象
     */
    public JwtAccessTokenConverter jwtAccessTokenConverter(){
        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
        jwtAccessTokenConverter.setSigningKey(sign_key); //签名秘钥
        jwtAccessTokenConverter.setVerifier(new MacSigner(sign_key)); //验证时使用的秘钥，和签名密钥保持一致
        jwtAccessTokenConverter.setAccessTokenConverter(lagouAccessTokenConvertor);
        return jwtAccessTokenConverter;
    }

}
